import json
from xmlrpc.client import boolean
from docx import Document
from docx.shared import Pt
import requests
import os

class Swagger2WordController:
    def __init__(self, view):
        self.view = view

    def handle_button_click(self, window_number):
        message = f"Window {window_number} clicked!"
        self.view.show_message(message)

    def load_swagger_json(self, url_or_path):
        # 根据URL或本地路径加载Swagger JSON数据
        if url_or_path.startswith('http'):
            # 如果是URL，则使用requests获取
            response = requests.get(url_or_path)
            response.raise_for_status()  # 检查请求是否成功
            return response.json()
        else:
            # 如果是本地文件路径，则直接打开文件
            with open(url_or_path, 'r', encoding='utf-8') as file:
                return json.load(file)

    def add_parameter_table(self, document, parameters, parent_name=""):
        # 添加参数表格，支持嵌套对象
        if not parameters:
            return

        table = document.add_table(rows=1, cols=4)
        table.style = 'Table Grid'  # 使用内置的表格风格
        hdr_cells = table.rows[0].cells
        hdr_cells[0].text = '参数名称'
        hdr_cells[1].text = '参数说明'
        hdr_cells[2].text = '请求类型'
        hdr_cells[3].text = '是否必须'

    def get_definitions(self, swagger_data, ref):
        # 根据$ref解析并返回定义的对象
        ref_path = ref.split('/')[-1]
        return swagger_data['definitions'][ref_path]

    def add_dict_parameters(self, table, properties, swagger_data, parent_name=''):
        for key, value in properties.items():
            name = f"   {key}" if parent_name else key
            description = value.get('description', '')
            param_type = value.get('type', '')
            required = str(not value.get('allowEmptyValue', boolean))

            # 添加普通参数
            row_cells = table.add_row().cells
            row_cells[0].text = name
            row_cells[1].text = description
            row_cells[2].text = param_type
            row_cells[3].text = required
            # 下面是处理对象里面有对象的情况，但是容易造成递归超过限制
            # if '$ref' in value:
            #     # 处理引用的定义
            #     definition = get_definitions(swagger_data, value['$ref'])
            #     properties = definition.get('properties', [])
            #     if isinstance(properties, list):
            #         add_list_parameters(table, properties, swagger_data, name)
            #     elif isinstance(properties, dict):
            #         add_dict_parameters(table, properties, swagger_data, name)
            # elif 'items' in value and '$ref' in value['items']:
            #     # 处理数组中的引用定义
            #     definition = get_definitions(swagger_data, value['items']['$ref'])
            #     properties = definition.get('properties', [])
            #     if isinstance(properties, list):
            #         add_list_parameters(table, properties, swagger_data, name)
            #     elif isinstance(properties, dict):
            #         add_dict_parameters(table, properties, swagger_data, name)

    def add_list_parameters(self, table, parameters, swagger_data, parent_name=''):
        """递归添加复杂参数到表格"""
        for param in parameters:
            name = f"   {param}" if parent_name else param['name']
            description = param.get('description', '')
            param_type = param.get('type', '')
            required = str(param.get('required', ''))

            row_cells = table.add_row().cells
            row_cells[0].text = name
            row_cells[1].text = description
            row_cells[2].text = param_type
            row_cells[3].text = required

            if 'schema' in param and '$ref' in param['schema']:
                # 处理引用的定义
                definition = self.get_definitions(swagger_data, param['schema']['$ref'])
                properties = definition.get('properties', [])
                if isinstance(properties, list):
                    self.add_list_parameters(table, properties, swagger_data, name)
                elif isinstance(properties, dict):
                    self.add_dict_parameters(table, properties, swagger_data, name)
            elif 'items' in param and '$ref' in param['items']:
                # 处理数组中的引用定义
                definition = self.get_definitions(swagger_data, param['items']['$ref'])
                properties = definition.get('properties', [])
                self.add_list_parameters(table, properties, swagger_data, name + '[]')
                if isinstance(properties, list):
                    self.add_list_parameters(table, properties, swagger_data, name)
                elif isinstance(properties, dict):
                    self.add_dict_parameters(table, properties, swagger_data, name)

    def swagger_to_word(self, swagger_data, output_path):
        document = Document()

        # 添加标题
        title_style = document.styles['Title']
        title_style.font.size = Pt(16)  # 设置标题字体大小
        document.add_heading(swagger_data["info"]["title"], level=1).style = title_style

        summary_style = document.styles['Normal']
        summary_style.paragraph_format.space_before = Pt(5)  # 设置段落前空格
        summary_style.paragraph_format.space_after = Pt(5)  # 设置段落后空格

        # 遍历paths对象，添加每个API路径的信息
        for path, methods in swagger_data['paths'].items():
            for method, details in methods.items():
                heading_style = document.styles['Heading 1']
                heading_style.font.size = Pt(14)  # 设置一级标题字体大小
                document.add_heading(details.get('summary', ''), level=1).style = heading_style
                document.add_paragraph(f"接口地址：{path}", style=summary_style)
                document.add_paragraph(f"请求方式：{method.upper()}", style=summary_style)
                document.add_paragraph(f"请求数据类型：{details.get('consumes', '')}", style=summary_style)
                document.add_paragraph(f"响应数据类型：{details.get('produces', '')}", style=summary_style)

                parameters = details.get('parameters', [])
                document.add_paragraph("请求参数：")
                if parameters:
                    table = document.add_table(rows=1, cols=4)
                    table.style = 'Table Grid'  # 使用内置的表格风格
                    hdr_cells = table.rows[0].cells
                    hdr_cells[0].text = '参数名称'
                    hdr_cells[1].text = '参数说明'
                    hdr_cells[2].text = '请求类型'
                    hdr_cells[3].text = '是否必须'

                    self.add_list_parameters(table, parameters, swagger_data)
                else:
                    document.add_paragraph("无")

                # 添加响应信息
                responses = details.get('responses', {})
                if responses:
                    document.add_paragraph("响应状态：")
                    table = document.add_table(rows=1, cols=4)
                    table.style = 'Table Grid'  # 使用内置的表格风格
                    hdr_cells = table.rows[0].cells
                    hdr_cells[0].text = '状态码'
                    hdr_cells[1].text = '说明'

                    for status_code, response in responses.items():
                        row_cells = table.add_row().cells
                        row_cells[0].text = status_code
                        row_cells[1].text = response.get('description', '')

                    document.add_paragraph("响应参数：")
                    result = responses["200"]
                    if 'schema' in result and '$ref' in result['schema']:
                        table = document.add_table(rows=1, cols=4)
                        table.style = 'Table Grid'  # 使用内置的表格风格
                        hdr_cells = table.rows[0].cells
                        hdr_cells[0].text = '参数名称'
                        hdr_cells[1].text = '参数说明'
                        hdr_cells[2].text = '类型'

                        self.add_list_parameters(table, parameters, swagger_data)
                    else:
                        document.add_paragraph("无")

        # 保存文档
        document.save(output_path)

    def swagger2word(self, input_file_path):
        # 输出Word文档的路径
        output_word_path = 'swagger接口文档'
        base_name = output_word_path
        extension = '.docx'

        i = 1
        while os.path.exists(f"{output_word_path}{extension}"):
            output_word_path = f"{base_name}({i})"
            i += 1

        output_word_path += extension

        # 加载Swagger JSON
        swagger_data = self.load_swagger_json(input_file_path)
        # 将Swagger JSON转换为Word文档
        self.swagger_to_word(swagger_data, output_word_path)

        return output_word_path

